package com.examination.filesystem.service.impl;

import com.alibaba.fastjson.JSON;
import com.examination.filesystem.dao.FileSystemRepository;
import com.examination.filesystem.service.FileSystemService;
import com.examination.framework.exception.ExceptionCast;
import com.examination.framework.model.response.CommonCode;
import com.examination.framework.model.response.ResponseResult;
import com.examination.system.filesystem.FileSystem;
import com.examination.system.filesystem.response.FileSystemCode;
import com.examination.system.filesystem.response.UploadFileResult;
import org.apache.commons.lang3.StringUtils;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Map;
import java.util.Optional;


/**
 * @author 寇淇芮
 * @Date 2019/7/20 19:31
 */
@Service
public class FileSystemServiceImpl implements FileSystemService {
    //日志文件
    private static final Logger LOGGER = LoggerFactory.getLogger(FileSystemServiceImpl.class);

    @Value("${examination.fastdfs.connect_timeout_in_seconds}")
    private Integer connect_timeout_in_seconds;
    @Value("${examination.fastdfs.network_timeout_in_seconds}")
    private Integer network_timeout_in_seconds;
    @Value("${examination.fastdfs.charset}")
    private String charset;
    @Value("${examination.fastdfs.tracker_servers}")
    private String tracker_servers;
    @Value("${examination.img.url}")
    private String imgUrl;

    @Autowired
    private FileSystemRepository fileSystemRepository;


    private StorageClient1 storageClient1 = null;
    /**
     * 添加文件上传
     *
     * @param multipartFile
     * @param filetag
     * @param businesskey
     * @param metadata
     * @return
     */
    @Override
    public UploadFileResult upload(MultipartFile multipartFile, String filetag, String businesskey, String metadata) {
        if (multipartFile == null) {
            ExceptionCast.cast(FileSystemCode.FS_UPLOADFILE_FILEISNULL);
        }
        //上传文件到fdfs
        String fileId = this.fdfs_upload(multipartFile);
        if (fileId == null) {
            ExceptionCast.cast(FileSystemCode.FS_UPLOADFILE_SERVERFAIL);
        }
        FileSystem fileSystem = new FileSystem();
        fileSystem.setFileId(fileId);
        //文件在文件系统中的路径
        fileSystem.setFilePath(fileId);
        //业务标识
        fileSystem.setBusinesskey(businesskey);
        //标签
        fileSystem.setFiletag(filetag);
        //元数据
        if (!StringUtils.isEmpty(metadata)) {
            Map map = JSON.parseObject(metadata, Map.class);
            fileSystem.setMetadata(map);
        }
        //名称
        fileSystem.setFileName(multipartFile.getName());
        //大小
        fileSystem.setFileSize(multipartFile.getSize());
        //文件类型
        fileSystem.setFileType(multipartFile.getContentType());
        //保存文件信息到数据库
        fileSystemRepository.save(fileSystem);

        return new UploadFileResult(CommonCode.SUCCESS,fileSystem);
    }

    @Override
    public ResponseResult delect(String url) {
        if(StringUtils.isEmpty(url)){
            ExceptionCast.cast(FileSystemCode.FS_INITFDFSERROR);
        }
        //去掉http://img.cqeeckaoshi.com/

        url = url.replace(imgUrl, "");

        FileSystem fileSystem = this.findFileSystemById(url);

        if(fileSystem == null){
            ExceptionCast.cast(FileSystemCode.FS_DELETEFILE_NOTEXISTS);
        }
        Boolean success = this.fdfs_delect(fileSystem.getFilePath());
        //判断是否删除
        if(success){
            fileSystemRepository.delete(fileSystem);
        }


        return success ? new ResponseResult(CommonCode.SUCCESS): new ResponseResult(CommonCode.FAIL);
    }
    private FileSystem findFileSystemById(String url){
        Optional<FileSystem> optional = fileSystemRepository.findById(url);
        return  optional.isPresent() ? optional.get(): null;
    }

    private String fdfs_upload(MultipartFile multipartFile) {

        try {
            if(storageClient1 == null){
                storageClient1 = this.initStorageClient1();
            }
            //上传文件
            //文件字节
            return storageClient1.upload_file1(multipartFile.getBytes(), multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().indexOf(".") + 1), null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private Boolean fdfs_delect(String url) {
        try {
            if(storageClient1 == null){
                storageClient1 = this.initStorageClient1();
            }
            //删除文件
            int i = storageClient1.delete_file1(url);
            //文件字节
            return i>0 ?true :false;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    private StorageClient1 initStorageClient1() throws IOException {
        this.initFdfsConfig();
        //创建tracker client
        TrackerClient trackerClient = new TrackerClient();
        //获取trackerServer
        TrackerServer trackerServer = trackerClient.getConnection();
        //获取storage
        StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer);
        //创建storage client
        return new StorageClient1(trackerServer, storeStorage);
    }
    /**
     * 配置服务器信息
     */
    private void initFdfsConfig() {
        try {
            ClientGlobal.initByTrackers(tracker_servers);
            ClientGlobal.setG_connect_timeout(connect_timeout_in_seconds);
            ClientGlobal.setG_network_timeout(network_timeout_in_seconds);
            ClientGlobal.setG_charset(charset);

        } catch (Exception e) {
            e.printStackTrace();
            ExceptionCast.cast(FileSystemCode.FS_INITFDFSERROR);
        }
    }
}
